#ifndef _BUFFER_H_
#define _BUFFER_H_

#include<iostream>
#include<thread>
#include<deque>
#include<mutex>
#include<condition_variable>
#include<stdio.h>
using namespace std;
template<typename T>
class buffer
{
private:
//typedef shared_ptr<mutex>  recoMutex;
//typedef shared_ptr<condition_variable> recoCond;
	deque<T>                    _content;
	mutex                       _mtx;
	condition_variable         _notEmptyCond;
	condition_variable         _notFullCond;   
	static const int SIZE       = 20;
public:
	buffer()
		//:_mtx2(new mutex()),
		//_notEmptyCond( new condition_variable()),
		//_notFullCond(new condition_variable())
	{
		//printf("Buffer initialized %p\n",_mtx2);
	}
	~buffer()
	{
	}
	void addItem(const T& item)
	{
		unique_lock<mutex> lock(_mtx);
		while ( _content.size() >= SIZE)
		{
			_notFullCond.wait(lock);
		}
		_content.push_back(item);
		_notEmptyCond.notify_all();
		lock.unlock();
	}
	T readItem()
	{
		unique_lock<mutex> lock(_mtx);
		while (_content.empty())
			_notEmptyCond.wait(lock);
		T ret = _content.front();
		_content.pop_front();
		_notFullCond.notify_all();
		lock.unlock();
		return ret;
	}
};
#endif
